package com.shanghaionstar.discover.geofence.presenter;

import android.app.Activity;
import android.content.Intent;
import android.os.Message;

import com.onstar.cn.common.exception.OnStarException;
import com.onstar.cn.common.util.CommonUtil;
import com.onstar.cn.common.util.Constants;
import com.onstar.cn.common.util.DeviceUtil;
import com.onstar.cn.framework.mvp.base.IMVPScheduler;
import com.onstar.cn.framework.mvp.base.IMVPView;
import com.onstar.cn.framework.mvp.base.core.BaseActivity;
import com.onstar.cn.framework.mvp.base.core.BasePresenter;
import com.onstar.cn.framework.utils.RxBus;
import com.onstar.cn.mag.GeofenceInfoEntity;
import com.onstar.cn.mag.enumtype.RemoteCommandsType;
import com.onstar.cn.mag.poi.Coordinate;
import com.onstar.cn.map.MapSearch;
import com.onstar.cn.map.common.PoiItemInfo;
import com.onstar.cn.map.util.MessageHandler;
import com.onstar.cn.more.response.PersonalInfoResponse;
import com.onstar.cn.rxconstants.RxConstants;
import com.onstar.cn.vehicle.entity.RequestStatus;
import com.onstar.cn.vehicle.result.PollingResult;
import com.shanghaionstar.R;
import com.shanghaionstar.discover.geofence.GeofenceCenterActivity;
import com.shanghaionstar.discover.geofence.GeofenceDetailActivity;
import com.shanghaionstar.discover.geofence.iview.IGeofenceInfoView;
import com.shanghaionstar.discover.geofence.service.GeofenceService;
import com.shanghaionstar.pin.PinDialogFragment;
import com.shanghaionstar.remote.model.RemoteModel;
import com.shanghaionstar.remote.service.RemoteService;
import com.shanghaionstar.utils.AlertDialogUtil;
import com.shanghaionstar.utils.BusinessUtil;
import com.shanghaionstar.utils.LoadCityList;
import com.shanghaionstar.weight.CommonInputLayout;

import java.util.List;
import java.util.Locale;

import rx.Observable;
import rx.Subscription;
import rx.functions.Action1;
import rx.functions.Func1;

/**
 * Created by 7828wc on 16/7/21.
 */
public class GeofenceInfoPresenter extends BasePresenter<GeofenceInfoEntity> {
    public static final int MAX_GEOFENCENAME_INPUT = 16;
    public static final int REQUEST_CODE_CENTER = 2;
    private GeofenceService service;
    private IGeofenceInfoView view;
    private BaseActivity mContext;

    private boolean isUpdate = false;
    private boolean isOnTouchMobile = false;
    private String subscriberPhone = "";//存储用户的手机号
    private int unit_km_dsa = -1;//记录选择的围栏半径单位，处理单位问题
    private String geoFencingStatus = "";//存储Geofence开关
    private String centerPoiAddress = "";//围栏中心详细地址

    //一些从其他地方传过来的值信息
    private String latitude = "";
    private String longitude = "";
    private String geoFenceId;
    private String expiredDate;
    private MapSearch mapSearch;

    private GeofenceInfoEntity geoFenceInfo;

    private Subscription pollingSubscription;

    public GeofenceInfoPresenter(IMVPScheduler mvpScheduler) {
        super(mvpScheduler);
        registerPollingSub();
    }

    @Override
    public void setView(IMVPView<GeofenceInfoEntity> view) {
        super.setView(view);
        service = new GeofenceService(view.onActivity());
        this.view = (IGeofenceInfoView) view;
        mContext = (BaseActivity) view.onActivity();
    }

    public void getOwnerMobile() {
        if(isUpdate || isOnTouchMobile){
            view.showMobile("");
            return;
        }
        subscription = service.init().flatMap(new Func1<String, Observable<PersonalInfoResponse>>() {
            @Override
            public Observable<PersonalInfoResponse> call(String entity) {
                return service.getOwnerMobilePhone();
            }
        }).subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread()).subscribe(new Action1<PersonalInfoResponse>() {
                    @Override
                    public void call(PersonalInfoResponse geofenceList) {
                        view.setLoading(false);
                        if (!isOnTouchMobile && !isUpdate) {
                            view.showMobile(geofenceList != null ? geofenceList.getPhoneNumber() : "");
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        //抛出Error异常
                        if (view != null) {
                            view.setLoading(false);
                            view.showMobile("");
                        }
                    }
                });
    }

    public boolean verifyUserPhone(CommonInputLayout inputLayout) {
        inputLayout.setEnabled(false);
        if (checkIsNull(inputLayout, R.string.input_mobile_empty)) return false;
        if (!CommonUtil.isPhone(inputLayout.getText())) {
            view.verifyResult(inputLayout, R.string.new_phone_error);
            return false;
        }
        return true;
    }

    public boolean checkIsNull(CommonInputLayout inputLayout, int resId) {
        if (CommonUtil.isNull(inputLayout.getText())) {
            view.verifyResult(inputLayout, resId);
            return true;
        }
        return false;
    }

    public String getRangeUnit(GeofenceInfoEntity entity) {
        return entity.getRangeUnit().equalsIgnoreCase("KM") ? mContext.getString(R.string.geofence_range_unit_km) : mContext.getString(R.string.geofence_range_unit_m);
    }

    public void getIntent() {
        isUpdate = mContext.getIntent().getBooleanExtra("isUpdate", false);
        if (isUpdate) {
            geoFenceInfo = (GeofenceInfoEntity) mContext.getIntent().getSerializableExtra(GeofenceInfoEntity.GEOFENCE_TAG);
            view.displayView(geoFenceInfo);
            expiredDate = geoFenceInfo.getExpiredDate();
            geoFenceId = geoFenceInfo.getGeoFencingID();
            latitude = geoFenceInfo.getCenterPoiCoordinate().getLatitude() + "";
            longitude = geoFenceInfo.getCenterPoiCoordinate().getLongitude() + "";
            centerPoiAddress = geoFenceInfo.getCenterPoiAddress();
            geoFencingStatus = geoFenceInfo.getGeoFencingStatus();
        }
    }

    public void setupGeoFenceInfo(String[] args){
        geoFenceInfo = setSetupGeoFenceInfo(args);
    }


    public GeofenceInfoEntity setSetupGeoFenceInfo(String[] args) {
        assert args.length == 5;
        String sRange = "";
        String numberRange = "";
        String unitRange = "";
        if (unit_km_dsa > -1) {
            if (!CommonUtil.isNull(args[0])) {
                sRange = args[0];
                if (unit_km_dsa < 1) {
                    unitRange = mContext.getString(R.string.geofence_range_unit_m).toLowerCase(Locale.CHINA);
                } else {
                    unitRange = mContext.getString(R.string.geofence_range_unit_km).toLowerCase(Locale.CHINA);
                }
                numberRange = sRange.replace(unitRange, "");
            }
        } else {
            if (geoFenceInfo != null) {
                numberRange = geoFenceInfo.getRange();
                unitRange = geoFenceInfo.getRangeUnit();
            }
        }
        GeofenceInfoEntity geofenceInfoEntity = new GeofenceInfoEntity();
        geofenceInfoEntity.setMobilePhone(args[1]);
        geofenceInfoEntity.setGeoFencingName(args[2]);
        geofenceInfoEntity.setRule(args[3]);
        geofenceInfoEntity.setRange(numberRange);
        geofenceInfoEntity.setRangeUnit(unitRange);
        if (!CommonUtil.isNull(geoFencingStatus)) {
            geofenceInfoEntity.setGeoFencingStatus(geoFencingStatus);
        }
        geofenceInfoEntity.setGeoFencingID(geoFenceInfo == null || geoFenceInfo.getGeoFencingID() == null ? "" : geoFenceInfo.getGeoFencingID());
        geofenceInfoEntity.setCenterPoiName(args[4]);
        geofenceInfoEntity.setCenterPoiAddress(centerPoiAddress);
        Coordinate coordinate = new Coordinate();
        geofenceInfoEntity.setCenterPoiCoordinate(coordinate);
        return geofenceInfoEntity;
    }


    /**
     * @param @param mGeoFenceInfo
     * @param @param applicationContext
     * @throws
     * @Title: GeoFenceSetupToSubmitUpdate
     */
    public void GeoFenceSetupToSubmitUpdate(GeofenceInfoEntity geoFenceInfo, String operateTypeUpdate) {
        if (geoFenceInfo != null) {
            String rangeUnit = geoFenceInfo.getRangeUnit();
            if (rangeUnit.toUpperCase(Locale.CHINA).equals(mContext.getString(R.string.geofence_range_unit_m))) {
                String range = geoFenceInfo.getRange();
                if (range.contains(mContext.getString(R.string.geofence_range_unit_km)))
                    range = range.replace(mContext.getString(R.string.geofence_range_unit_km), "");
                if (range.contains(mContext.getString(R.string.geofence_range_unit_m)))
                    range = range.replace(mContext.getString(R.string.geofence_range_unit_m), "");

                geoFenceInfo.setRange(Double.parseDouble(range) / 1000 + "");
                geoFenceInfo.setRangeUnit(mContext.getString(R.string.geofence_range_unit_km));
            }
            geoFenceInfo.setOperationType(operateTypeUpdate);
            updateGeofencing(geoFenceInfo);
        }
    }

//    private Handler resultHandler = new Handler() {
//        @Override
//        public void handleMessage(Message msg) {
//            switch (msg.what) {
//                case Constants.GET_OWNERMOBILENUBMER:
//                    subscriberPhone = (String) msg.getData().getSerializable("owner_mobile_number");
//                    if (!isOnTouchMobile && !isUpdate) {
//                        accept_phone.setText(subscriberPhone);
//                    }
//                    break;
//                case Constants.SHOW_GEOFENCE_DETAIL:
//                    loading_progress.setVisibility(View.GONE);
//                    data_layout.setVisibility(View.VISIBLE);
//                    BusinessUtil.updateConfigValue(FinalConfigParams.GEOFENCENAME, "", GeofenceInfoActivity.this);
//                    GeoFenceInfo geoFenceInfo = (GeoFenceInfo) msg.getData().getSerializable(GeoFenceInfo.GEOFENCE_TAG);
//                    Intent intent = new Intent(GeofenceInfoActivity.this, GeofenceDetailActivity.class);
//                    intent.putExtra(GeoFenceInfo.GEOFENCE_TAG, geoFenceInfo != null ? geoFenceInfo : GeofenceInfoActivity.this.geoFenceInfo);
//                    startActivity(intent);
//                    finish();
//                    break;
//                case Constants.ERROR:
//                    ErrorInfo errorInfo1 = (ErrorInfo) msg.getData().getSerializable("errorInfo");
//                    if (errorInfo1 != null) {
//                        ErrorCodeUtil.ShowErrorSompMsg(GeofenceInfoActivity.this, errorInfo1);
//                    }
//                    loading_progress.setVisibility(View.GONE);
//                    data_layout.setVisibility(View.VISIBLE);
//                    break;
//                case Constants.SERVICE_RESPONSE_FAILURE:
//                    ErrorInfo errorInfo = (ErrorInfo) msg.getData().getSerializable("errorInfo");
//                    RemoteCommandsType commandType = (RemoteCommandsType) msg.getData().getSerializable("commandType");
//                    AlertDialogUtil.showResultAlertDialog(GeofenceInfoActivity.this, false, commandType, errorInfo);
//                    loading_progress.setVisibility(View.GONE);
//                    data_layout.setVisibility(View.VISIBLE);
//                    break;
//                case Constants.SERVICE_HTTP_ERROR:
//                    commandType = (RemoteCommandsType) msg.getData().getSerializable("commandType");
//                    HttpException e = (HttpException) msg.getData().getSerializable("HttpException");
//                    AlertDialogUtil.showDialogByExceptionCode(GeofenceInfoActivity.this, e);
//                    loading_progress.setVisibility(View.GONE);
//                    data_layout.setVisibility(View.VISIBLE);
//                    break;
//                default:
//                    break;
//            }
//        }
//    };

    public void getGeoFencings() {
        view.setLoading(true);
        subscription = service.init().flatMap(new Func1<String, Observable<List<GeofenceInfoEntity>>>() {
            @Override
            public Observable<List<GeofenceInfoEntity>> call(String entity) {
                return service.getGeofencing();
            }
        }).subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread()).subscribe(new Action1<List<GeofenceInfoEntity>>() {
                    @Override
                    public void call(List<GeofenceInfoEntity> geofenceList) {
                        view.setLoading(false);
                        Intent intent = new Intent(mContext, GeofenceDetailActivity.class);
                        intent.putExtra(GeofenceInfoEntity.GEOFENCE_TAG, geofenceList.get(0) != null ? geofenceList.get(0) : geoFenceInfo);
                        mContext.startActivity(intent);
                        mContext.finish();
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        //抛出Error异常
                        view.onResponseError((OnStarException) throwable);
                        view.setLoading(false);
                    }
                });

    }

    public void updateGeofencing(final GeofenceInfoEntity entity) {
        view.setLoading(true);
        subscription = service.init().flatMap(new Func1<String, Observable<String>>() {
            @Override
            public Observable<String> call(String str) {
                return service.processGeofencing(entity);
            }
        }).subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread()).subscribe(new Action1<String>() {
                    @Override
                    public void call(String geofenceList) {
                        view.setLoading(false);
                        if (CommonUtil.isNull(geofenceList)) {
                            AlertDialogUtil.showAlertDialog(mContext, R.string.dialog_warning, R.string.poi_not_city_str);
                        } else {
                           getGeoFencings();
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        //抛出Error异常
                        view.onResponseError((OnStarException) throwable);
                        view.setLoading(false);
                    }
                });

    }


    /**
     * @param @param  etstring
     * @param @param  maxLength
     * @param @return 设定文件
     * @return String    返回类型
     * @throws
     * @Title: calculationStr
     * @Description: 判断汉字
     */
    public String calculationStr(String etstring, int maxLength) {
        char[] ch = etstring.toCharArray();
        int verlength = 0;
        StringBuilder text = new StringBuilder();
        for (int i = 0; i < ch.length; i++) {
            if ((ch[i] >= 0x2E80 && ch[i] <= 0xFE4F) || (ch[i] >= 0xA13F && ch[i] <= 0xAA40) || ch[i] >= 0x80) { // 中文字符范围0x4e00
                verlength = verlength + 2;
            } else {
                verlength++;
            }
            if (verlength > maxLength) {
                return text.toString();
            }
            if (verlength <= maxLength) {
                text.append(ch[i]);
            }
        }
        return text.toString();
    }

    public boolean checkVehicleLocation() {
        if (!CommonUtil.isNull(centerPoiAddress) && centerPoiAddress.equalsIgnoreCase(mContext.getString(R.string.poi_route_vehicle_str))) {
            showPinOrNot();
            return true;
        }
        return false;
    }

    public void submit() {
        if (isUpdate) {
            if (!CommonUtil.isNull(latitude)
                    && !CommonUtil.isNull(longitude)) {
                geoFenceInfo.getCenterPoiCoordinate().setLatitude(Double.parseDouble(latitude));
                geoFenceInfo.getCenterPoiCoordinate().setLongitude(Double.parseDouble(longitude));
            }
            geoFenceInfo.setGeoFencingID(geoFenceId);
            geoFenceInfo.setExpiredDate(expiredDate);
            GeoFenceSetupToSubmitUpdate(geoFenceInfo,
                    Constants.OPERATE_TYPE_UPDATE);
            isUpdate = false;
        } else {
            geoFenceInfo.setGeoFencingID("");
            geoFenceInfo.setExpiredDate("");
            geoFenceInfo.getCenterPoiCoordinate().setLatitude(Double.parseDouble(latitude));
            geoFenceInfo.getCenterPoiCoordinate().setLongitude(Double.parseDouble(longitude));
            GeoFenceSetupToSubmitUpdate(geoFenceInfo,
                    Constants.OPERATE_TYPE_CREATE);
        }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_CENTER) {
            PoiItemInfo poiItemInfo = (PoiItemInfo) data.getSerializableExtra("poiItemInfo");
            if (poiItemInfo != null) {
                latitude = poiItemInfo.getLatitude() + "";
                longitude = poiItemInfo.getLongitude() + "";
                centerPoiAddress = poiItemInfo.getAddress();
                    view.onActivityResultView(poiItemInfo);
            }
        }
    }

    public void launchGeoCenter() {
        Intent intent = new Intent(mContext, GeofenceCenterActivity.class);
        mContext.startActivityForResult(intent, REQUEST_CODE_CENTER);
    }

    public void showPinOrNot() {
        if (BusinessUtil.isAutoSendPin(RemoteCommandsType.COMMANDS_LOCATION, mContext)) {
            getVehicleLocation();
        } else {
            showPinDialogFragment();
        }
    }

    /**
     * 处理Polling 返回结果
     */
    private void registerPollingSub() {
        pollingSubscription = RxBus.getDefault()
                .toObserverable(RxConstants.ALL_PAGE_ALERT, PollingResult.class)
                .subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread())
                .subscribe(new Action1<PollingResult>() {
                    @Override
                    public void call(PollingResult pollingResult) {
                        onResult(pollingResult);
//                        if (RequestStatus.Success.getStringValue().equalsIgnoreCase(pollingResult.getRequestStatus())) {
//                            onResult(pollingResult);
//                        }
                    }
                });
    }

    public void getVehicleLocation() {
        view.setLoading(true);
        RemoteService remoteService = new RemoteService(mContext);
        RemoteModel remoteModel = new RemoteModel.Builder()
                .setRemoteCommandsType(RemoteCommandsType.COMMANDS_LOCATION)
                .create();
        subscription = remoteService.commandByType(remoteModel)
                .subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {

                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        //里面抛出的Error信息
                        if (view != null) {
                            view.setLoading(false);
                            view.onResponseError((OnStarException) throwable);
                        }
                    }
                });

    }

    private void showPinDialogFragment() {
        PinDialogFragment pinDialogFragment = PinDialogFragment.newInstance(RemoteCommandsType.COMMANDS_GEOFENCE_LOCATION, RxConstants.VEHICLE_LOCATE);
        pinDialogFragment.show(mContext.getSupportFragmentManager(), "pin_dialog");
    }


   public void onResult(final PollingResult result) {
        if (!CommonUtil.isNull(result) && result.getRequestStatus().equalsIgnoreCase(RequestStatus.Success.getStringValue()) && !CommonUtil.isNull(result.getLat())) {
            mapSearch = new MapSearch(mContext, null, new MessageHandler(null) {
                @Override
                public void handleMessage(Message msg) {
                    view.setLoading(false);
                    switch (msg.what) {
                        case com.onstar.cn.map.common.Constants.SEARCH_ERRORS:
                            AlertDialogUtil.showAlertDialog(mContext, R.string.dialog_warning, R.string.poi_no_search);
                            break;
                        case com.onstar.cn.map.common.Constants.REVERSE_GEOCODE_RESULT:
                            PoiItemInfo poi = (PoiItemInfo) msg.obj;
                            String mSelectCity = poi.getCityName();
                            if (DeviceUtil.getLanguage().equalsIgnoreCase("en")) {
                                LoadCityList loadFile = new LoadCityList(mContext);
                                poi.setCityName(loadFile.findByZhCity(mSelectCity));
                            }
                            latitude = poi.getLatitude() + "";
                            longitude = poi.getLongitude() + "";
                            centerPoiAddress = poi.getAddress();
                            view.onResultView(centerPoiAddress);
                            view.commitData();
                            break;
                        default:
                            break;
                    }
                }
            });
            mapSearch.geoCoderGps(Double.parseDouble(result.getLat()), Double.parseDouble(result.getLon()));
        } else {
            view.setLoading(false);
            if(result == null || result.getErrorInfo() == null)
                return;
            if (!CommonUtil.isNull(result.getErrorInfo().getMsg())) {
                AlertDialogUtil.showResultSystemAlertDialog(mContext, true, RemoteCommandsType.COMMANDS_LOCATION, result.getErrorInfo());
            } else {
                AlertDialogUtil.showResultAlertDialog(mContext, false, RemoteCommandsType.COMMANDS_LOCATION, result.getErrorInfo());
            }
        }

    }

    public void rangeClick(int which) {
        this.unit_km_dsa = which;
    }

    public void onTouch() {
        isOnTouchMobile = true;
    }

    @Override
    public void finish() {
        super.finish();
        if(pollingSubscription != null && !pollingSubscription.isUnsubscribed())
            pollingSubscription.unsubscribe();
    }
}
